//
// Created by Felix on 24-4-26.
//

#ifndef GAZE_AUTHCONTROLLER_HPP
#define GAZE_AUTHCONTROLLER_HPP

#include "oatpp/web/server/api/ApiController.hpp"
#include "oatpp/core/macro/component.hpp"
#include "oatpp/core/macro/codegen.hpp"

#include "service/AuthService.hpp"
#include "dto/DTOs.hpp"
#include "dto/SignInDto.hpp"

#include OATPP_CODEGEN_BEGIN(ApiController)

class AuthController : public oatpp::web::server::api::ApiController {
public:
    explicit AuthController(
            OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper)
    ) : oatpp::web::server::api::ApiController(objectMapper) {}

    static std::shared_ptr<AuthController> createShared(
            OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper)
    ) {
        return std::make_shared<AuthController>(objectMapper);
    }

private:
    AuthHandler iAuthHandler;
    AuthService iAuthService; // Create user service.
public:
    ENDPOINT_INFO(signIn) {
        info->addTag("Auth");
        info->summary = "Sign in";
        info->description = "在需要权限的接口里，需要在请求头里添加 Authorization，携带 token  的值。";
        info->addConsumes < Object < SignInDto > > ("application/json");
        info->addResponse < Object < MessageDtoComposeAuthDto > > (Status::CODE_200, "application/json");
        info->addResponse < Object < MessageDto<> > > (Status::CODE_401,
                "application/json", R"(输出：{"status_code":401,"status":"ERROR","message":"Unauthorized","data":[]})"
        );
        info->addResponse < Object < MessageDto<> > > (Status::CODE_500, "application/json");

        auto signInDto = SignInDto::createShared();
        signInDto->username = "admin";
        signInDto->password = "admin";
        auto jsonObjectMapper = oatpp::parser::json::mapping::ObjectMapper::createShared();
        oatpp::String json = jsonObjectMapper->writeToString(signInDto);

        info->body.addExample("Sign In", oatpp::String(json->c_str()));
    } // Sign in
    ENDPOINT("POST", "/api/auth/sign_in", signIn,
             BODY_DTO(Object < SignInDto > , dto)) {
        oatpp::Object<MessageDtoComposeAuthDto> message = MessageDtoComposeAuthDto::createShared();
        message->status = "OK";
        message->statusCode = 200;
        message->message = "登录成功";
        message->data = iAuthService.signIn(dto);
        return createDtoResponse(Status::CODE_200, message);
    }

    ENDPOINT_INFO(signOut) {
        info->addTag("Auth");
        info->summary = "Sign out";
        info->description = "需要在请求头里添加 Authorization，携带 token  的值。";
        info->authorization = ""; // <-- 没有这一行，无法声明需要授权
        info->addSecurityRequirement("basic_auth");
        info->addResponse < Object < MessageDtoComposeVector > > (Status::CODE_200, "application/json");
        info->addResponse < Object < MessageDto<> > > (Status::CODE_401,
                "application/json", R"(输出：{"status_code":401,"status":"ERROR","message":"Unauthorized","data":[]})"
        );
    } // Sign out
    ENDPOINT("GET", "/api/auth/sign_out", signOut,
             REQUEST(std::shared_ptr<IncomingRequest>, request)) {
        auto token = AuthHandler::token(request->getHeader(oatpp::web::protocol::http::Header::AUTHORIZATION));
        if (!token->empty())iAuthService.signOut(token);

        auto message = MessageDtoComposeVector::createShared();
        message->status = "OK";
        message->statusCode = 200;
        message->message = "登出成功";
        message->data = oatpp::Vector<oatpp::Any>({});
        return createDtoResponse(Status::CODE_200, message);
    }
};

#include OATPP_CODEGEN_END(ApiController)

#endif //GAZE_AUTHCONTROLLER_HPP
